package com.yupi.yuojcodesandbox;

import cn.hutool.core.date.StopWatch;
import cn.hutool.core.io.FileUtil;
import cn.hutool.core.lang.UUID;
import org.junit.jupiter.api.Test;
import org.springframework.boot.test.context.SpringBootTest;

import java.io.*;
import java.nio.charset.StandardCharsets;

/**
 * @Author:Dong
 * @Date: 2024/4/20  17:55
 * @Version 1.0
 */
@SpringBootTest
public class executeCode {

    public static void main(String[] args) throws IOException, InterruptedException {
        String GLOBAL_CODE_DIR_NAME = "Dong";
        String GLOBAL_JAVA_CLASS_NAME = "SimpleCompute.java";
        String userDir = System.getProperty("user.dir");
        String globalCodePathName = userDir + File.separator + GLOBAL_CODE_DIR_NAME;
// 判断全局代码目录是否存在，没有则新建
        if (!FileUtil.exist(globalCodePathName)) {
            FileUtil.mkdir(globalCodePathName);
        }
        String code = "\n" +
                "public class SimpleCompute {\n" +
                "    public static void main(String[] args) {\n" +
                "        int a = Integer.parseInt(args[0]);\n" +
                "        int b = Integer.parseInt(args[1]);\n" +
                "        System.out.println(\"结果:\" + (a + b));\n" +
                "    }\n" +
                "}";

        // 把用户的代码隔离存放
        String userCodeParentPath = globalCodePathName + File.separator + UUID.randomUUID();
        String userCodePath = userCodeParentPath + File.separator + GLOBAL_JAVA_CLASS_NAME;
        File userCodeFile = FileUtil.writeString(code, userCodePath, StandardCharsets.UTF_8);
        String compileCmd = String.format("javac -encoding utf-8 %s", userCodeFile.getAbsolutePath());
        Process process = Runtime.getRuntime().exec(compileCmd);

        int exitValue = process.waitFor();
        InputStream inputStream = process.getInputStream();
// 正常退出
        if (exitValue == 0) {
            System.out.println("编译成功");
            // 分批获取进程的正常输出
            BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(process.getInputStream()));
            StringBuilder compileOutputStringBuilder = new StringBuilder();
            // 逐行读取
            String compileOutputLine;
            while ((compileOutputLine = bufferedReader.readLine()) != null) {
                compileOutputStringBuilder.append(compileOutputLine);
            }
            System.out.println(compileOutputStringBuilder);
        } else {
            // 异常退出
            System.out.println("编译失败，错误码： " + exitValue);
            // 分批获取进程的正常输出
            BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(process.getInputStream()));
            StringBuilder compileOutputStringBuilder = new StringBuilder();
            // 逐行读取
            String compileOutputLine;
            while ((compileOutputLine = bufferedReader.readLine()) != null) {
                compileOutputStringBuilder.append(compileOutputLine);
            }
            // 分批获取进程的错误输出
            BufferedReader errorBufferedReader = new BufferedReader(new InputStreamReader(process.getErrorStream()));
            StringBuilder errorCompileOutputStringBuilder = new StringBuilder();

            // 逐行读取
            String errorCompileOutputLine;
            while ((errorCompileOutputLine = errorBufferedReader.readLine()) != null) {
                errorCompileOutputStringBuilder.append(errorCompileOutputLine);
            }
            System.out.println(compileOutputStringBuilder);
        }
    }

    @Test
    void tDemo1() throws IOException, InterruptedException {
        String GLOBAL_CODE_DIR_NAME = "Dong";
        String GLOBAL_JAVA_CLASS_NAME = "SimpleCompute.java";
        String userDir = System.getProperty("user.dir");
        String globalCodePathName = userDir + File.separator + GLOBAL_CODE_DIR_NAME;
// 判断全局代码目录是否存在，没有则新建
        if (!FileUtil.exist(globalCodePathName)) {
            FileUtil.mkdir(globalCodePathName);
        }
        String code = "\n" +
                "public class SimpleCompute {\n" +
                "    public static void main(String[] args) {\n" +
                "        int a = Integer.parseInt(args[0]);\n" +
                "        int b = Integer.parseInt(args[1]);\n" +
                "        System.out.println(\"结果:\" + (a + b));\n" +
                "    }\n" +
                "}";

        // 把用户的代码隔离存放
        String userCodeParentPath = globalCodePathName + File.separator + UUID.randomUUID();
        String userCodePath = userCodeParentPath + File.separator + GLOBAL_JAVA_CLASS_NAME;
        File userCodeFile = FileUtil.writeString(code, userCodePath, StandardCharsets.UTF_8);
        String compileCmd = String.format("javac -encoding utf-8 %s", userCodeFile.getAbsolutePath());
        Process process = Runtime.getRuntime().exec(compileCmd);

        int exitValue = process.waitFor();
// 正常退出
        if (exitValue == 0) {
            System.out.println("编译成功");
            // 分批获取进程的正常输出
            BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(process.getInputStream()));
            StringBuilder compileOutputStringBuilder = new StringBuilder();
            // 逐行读取
            String compileOutputLine;
            while ((compileOutputLine = bufferedReader.readLine()) != null) {
                compileOutputStringBuilder.append(compileOutputLine);
            }
            System.out.println(compileOutputStringBuilder);
        } else {
            // 异常退出
            System.out.println("编译失败，错误码： " + exitValue);
            // 分批获取进程的正常输出
            BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(process.getInputStream()));
            StringBuilder compileOutputStringBuilder = new StringBuilder();
            // 逐行读取
            String compileOutputLine;
            while ((compileOutputLine = bufferedReader.readLine()) != null) {
                compileOutputStringBuilder.append(compileOutputLine);
            }
            // 分批获取进程的错误输出
            BufferedReader errorBufferedReader = new BufferedReader(new InputStreamReader(process.getErrorStream()));
            StringBuilder errorCompileOutputStringBuilder = new StringBuilder();

            // 逐行读取
            String errorCompileOutputLine;
            while ((errorCompileOutputLine = errorBufferedReader.readLine()) != null) {
                errorCompileOutputStringBuilder.append(errorCompileOutputLine);
            }
            System.out.println(compileOutputStringBuilder);
        }
    }

    @Test
    void Execute() throws IOException {
        String userCodeFile = "D:\\dysJavaProject\\yuoj-code-sandbox\\src\\main\\resources\\code\\Main.java";
        ProcessBuilder pb = new ProcessBuilder("javac", "-encoding", "utf-8", userCodeFile);
        Process process = pb.start();
        System.out.println("process.toString() = " + process.toString());
        //执行java命令，运行java代码
        String MainName = "Main";
        pb = new ProcessBuilder("java","-cp","D:\\dysJavaProject\\yuoj-code-sandbox\\src\\main\\resources\\code",MainName);
        // 分批获取进程的正常输出
        BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(process.getInputStream()));
        StringBuilder compileOutputStringBuilder = new StringBuilder();
        // 逐行读取
        String compileOutputLine;
        while ((compileOutputLine = bufferedReader.readLine()) != null) {
            compileOutputStringBuilder.append(compileOutputLine);
        }
        System.out.println(compileOutputStringBuilder);
    }

    @Test
    void getOutput2() throws IOException, InterruptedException {
        StopWatch stopWatch = new StopWatch();
        stopWatch.start();
        ProcessBuilder pb = new ProcessBuilder();
        String MainName = "Main";
        pb = new ProcessBuilder("java","-cp","D:\\dysJavaProject\\yuoj-code-sandbox\\src\\main\\resources\\code",MainName);
        Process process = pb.start();
        int i = process.waitFor();
        if (i == 0){
            System.out.println("\"执行成功\" = " + "执行成功");
        }
        // 分批获取进程的正常输出
        BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(process.getInputStream()));
        StringBuilder compileOutputStringBuilder = new StringBuilder();
        // 逐行读取
        String compileOutputLine;
        while ((compileOutputLine = bufferedReader.readLine()) != null) {
            compileOutputStringBuilder.append(compileOutputLine);
        }
        System.out.println(compileOutputStringBuilder);
    }
    }


